#ifndef VISBASECONTAINER_H
#define VISBASECONTAINER_H

#include <QObject>
#include <QGraphicsWidget>
#include <QDebug>
#include <QGraphicsItem>
#include <QPointer>
#include <QThread>

#include "visbaseelement.h"

//Forward declarations to avoid circular dependencies
class VisBaseElement;
class SageVis;
class VisBaseWidget;
class VisBaseLayout;

/** VisBaseContainer class.
  * The main goal of a vis base container is to store and layout elements.
  *     For instance:   a container full of nodes in a graph could be lay-ed out using a force directed layout
  *                     a container full of labels could be lay-ed out vertically- each label atop the next.
  * Eventually, I may create easy mechanisms for connecting elements in two different containers together.
  *     For instance:   two containers of nodes connected, so nodes of the same type are highlighted together.
  *                     a container of labels, lay-ed out vertically, connected to a container of timelines, also lay-ed out vertically.
  * Right now:  elements in different containers are connected directly- element to element.
  *
  *
  * LAYOUT
  * Containers are given a layout for their elements
  * Once elements are added to the layout, then the widget processes the layout on a new thread.
  * For more information see 'How does layout work' in the vis base widget class
  */

class VisBaseContainer : public VisBaseElement
{
    Q_OBJECT
public:
    VisBaseContainer(QPointer<SageVis> sageVisPointer, QPointer<VisBaseWidget> parentWidget, QGraphicsItem *parent = 0);
    //~VisBaseContainer();

    void addElement(QPointer< VisBaseElement > e);/*<adds element to the container and connects element 'recomputeLayoutSignal' to 'recomputeLayoutSlot'*/

    //----------LAYOUT------------
    void setLayout( VisBaseLayout* layout );//layout for elements in the container is set.
    void layoutElements();//process the layout of the elements- send vis base widget the signal to run stored layout.
    void layoutElements( VisBaseLayout* layout );//both pass this container a layout and signal vis base widget to run the stored layout.
    void layoutElementsNonThreaded();//Not using right now, but could layout elements without passing layout to new thread.  Before using, check to see if it still works.
    void layoutElementsNonThreaded( VisBaseLayout* layout );//Not using right now, but could layout elements without moving to thread.  Before using, check to see if it still works.

    //-----------HEIGHT, WIDTH, XPos, YPos of ELEMENTS-------------
    void setWidthOfElements( int w ); //give elements a uniform width
    void setHeightOfElements( int h ); //give elements a uniform height
    void setWidthAndHeightOfElements( int w, int h );//give elements uniform dimensions
    void setXPosOfElements( int xPos ); //can line them up vertically
    void setYPosOfElements( int yPos ); //can line them up horizontally
    void setPosOfElements( int x, int y ); //all in one place

    void setWidthOfElements( float w ); //uniform width
    void setHeightOfElements( float h ); //uniform height
    void setWidthAndHeightOfElements( float w, float h );
    void setXPosOfElements( float xPos ); //can line them up vertically
    void setYPosOfElements( float yPos ); //can line them up horizontally
    void setPosOfElements( float x, float y ); //all in one place

    //-----------CONNECT CONTAINER TO ELEMENTS---------------
    void connectContainerToElements(int type);//specify a connection between the container and all the elements in the container.
    void connectElementsToContainer(int type);//specify a connection between all the elements in the container and the container.
    void connectTwoWayElementsToContainer(int type);//specify a two-way connection between elements and container

    //---------- GET SIZE AND SHAPE INFO ABOUT OBJECTS IN CONTAINER ----------
    float getMaxElementWidth();//what is the maximum element width in this container.

    //SHAPE AND SIZE FUNCTIONS
    //  Not using right now because container is not drawn.
//    void setGeometry(const QRectF &geom);
//    void setGeometry( qreal x, qreal y, qreal w, qreal h );
//    QRectF boundingRect() const;
//    QPainterPath shape() const;
signals:
    void runLayoutSignal( VisBaseLayout* layout );//when layout is called
    
public slots:
    /** Advance function allows for animation within VisWidgets.
      * This function is implemented in derived classes
      */
    void advance();
    void callUpdate();
    void recomputeLayoutSlot();
    void moveLayoutBackToThisThread();

protected:
//    QPointer<SageVis> sageVisPointer;/*< Pointer to the SageVis parent that controls this widget. */
//    QPointer<VisBaseWidget> parentWidget;

    QList< QPointer<VisBaseElement> > elements;

    QRectF containerBoundingRect;
    float maxElementWidth;

    VisBaseLayout* layout;
};

#endif // VISBASECONTAINER_H
